package com.huawei.aiosproj.guiagent;

import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.GestureDescription;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.huawei.aiosproj.R;
import com.huawei.aiosproj.engine.LLMEngineRequest;
import com.huawei.aiosproj.utils.ApplicationUtils;
import com.huawei.aiosproj.utils.GUIResult;
import com.huawei.aiosproj.utils.ReflectUtils;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GUIAgentService extends AccessibilityService {
    private Context context;
    private static int task_step = 0;
    private static final String TAG = "GUIAgentService";

    private WindowManager windowManager;
    private View floatingView;
    private WindowManager.LayoutParams params;
    private TextView llmActionTextView;

    private LLMEngineRequest llmEngineRequest; // Member variable
    private String currentGlobalTaskPrompt;

    public InputStream getImageInputStream(String imagePath) {
        try {
            File file = new File(imagePath);
            return new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        }
    }

    public GUIAgentService() {
    }

    @Override
    public void onAccessibilityEvent(AccessibilityEvent event) {
        // ... your existing onAccessibilityEvent code ...
        // If you want to trigger startNewGlobalTask from a button in the floating window:
        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_CLICKED) {
            AccessibilityNodeInfo sourceNode = event.getSource();
            if (sourceNode != null) {
                // Assuming your button in the floating window has this content description
                // Or you can identify it by its view ID if the floating window is part of the view hierarchy
                // that onAccessibilityEvent can see (which might not be the case for system overlays).
                // A more reliable way for system overlays is to set an OnClickListener directly in createFloatingWindow.
                if ("gui_agent_action_button".equals(sourceNode.getContentDescription() != null ? sourceNode.getContentDescription().toString() : "")) {
                    Log.d(TAG, "GUI Agent Action button clicked via AccessibilityEvent");
                    AccessibilityNodeInfo rootNode = getRootInActiveWindow();
                    if (rootNode != null) {
                        List<AccessibilityNodeInfo> editTextNodes = rootNode.findAccessibilityNodeInfosByViewId("com.huawei.aiosproj:id/userPrompt");
                        if (!editTextNodes.isEmpty()) {
                            AccessibilityNodeInfo editTextNode = editTextNodes.get(0);
                            if (editTextNode.getText() != null) {
                                String userCommand = editTextNode.getText().toString();
                                if (!userCommand.isEmpty()) {
                                    Log.i(TAG, "Starting new global task from floating window input: " + userCommand);
                                    startNewGlobalTask(userCommand);
                                } else {
                                    Log.w(TAG, "User command input is empty.");
                                    updateLLMActionDisplay("Please enter a command.");
                                }
                            }
                            editTextNode.recycle();
                        }
                        rootNode.recycle();
                    }
                }
                sourceNode.recycle();
            }
        }
    }

    private void updateLLMActionDisplay(final String text) {
        if (llmActionTextView != null) {
            // Ensure UI updates are on the main thread
            llmActionTextView.post(new Runnable() {
                @Override
                public void run() {
                    llmActionTextView.setText("LLM Action: " + text);
                }
            });
        } else {
            Log.w(TAG, "llmActionTextView is null, cannot update display.");
        }
    }

    @Override
    public void onInterrupt() {

    }

    private String postRequest(String fileName, String userPromptForThisStep, boolean isFirstStepOfGlobalTask) {
        File externalFilesDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File file = new File(externalFilesDir, fileName);
        Log.e(TAG, "获取要推理的截图地址：" + file.getPath());
        updateLLMActionDisplay("Processing: " + userPromptForThisStep.substring(0, Math.min(userPromptForThisStep.length(), 30)) + "..."); // Show initial status

        new Thread(() -> {
            try {
                String response = llmEngineRequest.runModel(file.getPath(), userPromptForThisStep);
                Log.e(TAG, "postRequest response: " + response);
                if (response == null) {
                    Log.e(TAG, "LLM response is null.");
                    updateLLMActionDisplay("Error: No response from LLM.");
                    return;
                }
                JSONObject root = new JSONObject(response);
                JSONArray choices = root.getJSONArray("choices");
                JSONObject choice = choices.getJSONObject(0);
                JSONObject message = choice.getJSONObject("message");
                String content = message.getString("content");

                // 提取Action行
                String actionLine = GUIResult.extractActionLine(content);
                int x = 0;
                int y = 0;
                boolean isActionLineNull = false;
                String action = "";
                String typeContent = "";
                if (actionLine == null) {
                    Log.e(TAG, "No valid action line found in content: " + content);
                    final String displayContent = content.length() > 100 ? content.substring(0, 97) + "..." : content;
//                    updateLLMActionDisplay("No action found. LLM says: " + displayContent);
                    Pattern pointPattern = Pattern.compile("point\\s*=\\s*'<point>\\s*(\\d+)\\s+(\\d+)\\s*</point>'");
                    Matcher pointMatcher = pointPattern.matcher(content); // Use 'content' directly

                    if (pointMatcher.find()) {
                        x = Integer.parseInt(pointMatcher.group(1));
                        y = Integer.parseInt(pointMatcher.group(2));
                        Log.i(TAG, "Parsed point directly from content: x=" + x + ", y=" + y);
                        action = "click"; // Assuming if a point is found, the action is click
                        isActionLineNull = true; // Set this to true to indicate we've handled it
                    } else {
                        Log.e(TAG, "Could not find point coordinates in content: " + content);
                        updateLLMActionDisplay("Error: Could not parse coordinates.");
                    }

                    String regex = "^type\\s*\\(\\s*content\\s*=\\s*'((?:\\\\'|[^'])*)'\\s*\\)$";
                    Pattern pattern = Pattern.compile(regex);
                    Matcher matcher = pattern.matcher(content);

                    if (matcher.find()) {
                        // The keyword "type" is fixed and matched, but not captured as a group by itself
                        // if we only care about the content. We can just assign it.
                        String fixedTypeKeyword = "type";
                        // Group 1 now contains the raw content due to the regex structure
                        typeContent = matcher.group(1).replace("\\'", "'");
                        action = "type"; // Assuming if a point is found, the action is click
                        isActionLineNull = true; // Set this to true to indicate we've handled it
                    } else {
                        Log.e(TAG, "Input text does not match the expected 'type(content=...)' format: " + content);
                    }

                }
                if (!isActionLineNull) {
                    Pattern actionPattern = Pattern.compile("^(\\w+)\\((.*)\\)$");
                    Matcher matcher = actionPattern.matcher(actionLine.trim());

                    if (!matcher.find()) {
                        Log.e(TAG, "Invalid action format: " + actionLine);
                        updateLLMActionDisplay("Invalid action: " + actionLine);
                        return;
                    }

                    action = matcher.group(1);
                    String paramsStr = matcher.group(2);
                    Log.e(TAG, "postRequest: paramsStr" + paramsStr);
                    boolean taskFinished = false;
                    Log.i(TAG, "Parsed Action: " + action + ", Params: " + paramsStr);

                    // ***** UPDATE THE FLOATING WINDOW TEXTVIEW *****
                    final String displayText = "Action: " + action + "\nParams: " + paramsStr;
                    updateLLMActionDisplay(displayText);
                    if (action.equals("click")) {
                        Log.e(TAG, "postRequest: " + "检测到click 事件，开始处理click 事件。");
                        Map<String, String> params = GUIResult.parseParams(action, paramsStr);
                        for (String key : params.keySet()) {
                            Log.e(TAG, "postRequest: KEY " + key);
                            Log.e(TAG, "postRequest: VALUE " + params.get(key));
                            String[] numbers = params.get(key).split("\\s+");
                            x = Integer.parseInt(numbers[0]);
                            y = Integer.parseInt(numbers[1]);
                        }
                        Log.e(TAG, "postRequest x : " + x);
                        Log.e(TAG, "postRequest y : " + y);

                        WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
                        Display display = windowManager.getDefaultDisplay();
                        Point size = new Point();
                        display.getSize(size);

                        BitmapFactory.Options options = new BitmapFactory.Options();
                        options.inJustDecodeBounds = true; // This is the crucial part
                        BitmapFactory.decodeFile(file.getAbsolutePath(), options);

                        int screenWidth = options.outWidth;
                        int screenHeight = options.outHeight;


//                        int screenWidth = size.x;
//                        int screenHeight = size.y;

//                        int screenWidth = size.x;
//                        int screenHeight = size.y;
                        Log.e(TAG, "postRequest: screenWidth:" + screenWidth);
                        Log.e(TAG, "postRequest: screenHeight:" + screenHeight);

                        double xNormalized = x / 1000.0;
                        double yNormalized = y / 1000.0;

                        int xAbsolute = (int) Math.round(xNormalized * screenWidth);
                        int yAbsolute = (int) Math.round(yNormalized * screenHeight);

//                    int xAbsolute = (int) ((x / 1000.0) * screenWidth);
//                    int yAbsolute = (int) ((y / 1000.0) * screenHeight);

//                    int xAbsolute = (int) (Math.round(((x + x) / 2.0) * screenWidth * 1000) / 1000.0);
//                    int yAbsolute = (int) (Math.round(((y + y) / 2.0) * screenHeight * 1000) / 1000.0);

//                    xAbsolute = Math.min(Math.max(xAbsolute, 0), screenWidth);
//                    yAbsolute = Math.min(Math.max(yAbsolute, 0), screenHeight);

                        Log.e(TAG, "agent 开始处理点击事件，事件转换后坐标，xAbsolute: " + xAbsolute);
                        Log.e(TAG, "agent 开始处理点击事件，事件转换后坐标，yAbsolute: " + yAbsolute);

                        Point point = new Point(xAbsolute, yAbsolute);
                        AccessibilityNodeInfo rootNode = getRootInActiveWindow();
                        if (rootNode != null) {
                            Log.e(TAG, "postRequest: " + "click begin.");
                            performClick(rootNode, point);
                        }
                        Thread.sleep(3000);
                        executeAgentTask(this.currentGlobalTaskPrompt, false);
                    } else if (action.equals("press_home")) {
                        Log.e(TAG, "postRequest: " + "检测到press_home事件，开始处理press_home事件。");
                        performGlobalAction(GLOBAL_ACTION_HOME);
                        Thread.sleep(1000);
                        executeAgentTask(this.currentGlobalTaskPrompt, false);
                    } else if (action.equals("finished")) {
                        taskFinished = true;
                        Log.e(TAG, "postRequest: " + "检测到finished事件，开始处理finished事件。");
                    } else if (action.equals("wait")) {
                        Log.e(TAG, "postRequest: " + "检测到wait事件，开始处理wait事件。");
                        Thread.sleep(5000);
                        executeAgentTask(this.currentGlobalTaskPrompt, false);
                    } else if (action.equals("press_back")) {
                        Log.e(TAG, "postRequest: " + "检测到press_back事件，开始处理press_back事件。");
                        performGlobalAction(GLOBAL_ACTION_BACK);
                        executeAgentTask(this.currentGlobalTaskPrompt, false);
                    } else if (action.equals("open_app")) {
                        Log.e(TAG, "postRequest: " + "检测到open_app事件，开始处理open_app事件。");
                        String DIDI_PACKAGE = "com.sdu.didi.psnger";
                        Intent trampolineIntent = new Intent(this, TrampolineActivity.class);
                        trampolineIntent.putExtra(TrampolineActivity.TARGET_PACKAGE_KEY, DIDI_PACKAGE);
                        trampolineIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(trampolineIntent);

                        Thread.sleep(1000);
                        executeAgentTask(this.currentGlobalTaskPrompt, false);
                    } else if (action.equals("type")) {
                        Log.e(TAG, "postRequest: " + "开始处理输入事件");
                        Pattern pattern = Pattern.compile("content='(.*?)'");
                        Matcher matcherStr = pattern.matcher(paramsStr);

                        if (matcherStr.find()) {
                            String contentType = matcherStr.group(1); // 提取第一个分组（括号内内容）
                            Log.e(TAG, "postRequest: 输出内容：" + contentType);

                            AccessibilityNodeInfo focusNode = getRootInActiveWindow().findFocus(AccessibilityNodeInfo.FOCUS_INPUT);
                            if (focusNode != null && "android.widget.EditText".equals(focusNode.getClassName())) {
                                Bundle bundle = new Bundle();
                                bundle.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, contentType);
                                focusNode.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, bundle);
                                Thread.sleep(2000);
                                executeAgentTask(this.currentGlobalTaskPrompt, false);
                            }
                        }
                    }
                } else {
                    if (action.equals("click")) {
                        isActionLineNull = false;
                        WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
                        Display display = windowManager.getDefaultDisplay();
                        Point size = new Point();
                        display.getSize(size);

                        BitmapFactory.Options options = new BitmapFactory.Options();
                        options.inJustDecodeBounds = true; // This is the crucial part
                        BitmapFactory.decodeFile(file.getAbsolutePath(), options);

                        int screenWidth = options.outWidth;
                        int screenHeight = options.outHeight;


//                        int screenWidth = size.x;
//                        int screenHeight = size.y;
                        Log.e(TAG, "postRequest: screenWidth:" + screenWidth);
                        Log.e(TAG, "postRequest: screenHeight:" + screenHeight);

                        double xNormalized = x / 1000.0;
                        double yNormalized = y / 1000.0;

                        int xAbsolute = (int) Math.round(xNormalized * screenWidth);
                        int yAbsolute = (int) Math.round(yNormalized * screenHeight);

//                    int xAbsolute = (int) ((x / 1000.0) * screenWidth);
//                    int yAbsolute = (int) ((y / 1000.0) * screenHeight);

//                    int xAbsolute = (int) (Math.round(((x + x) / 2.0) * screenWidth * 1000) / 1000.0);
//                    int yAbsolute = (int) (Math.round(((y + y) / 2.0) * screenHeight * 1000) / 1000.0);

//                    xAbsolute = Math.min(Math.max(xAbsolute, 0), screenWidth);
//                    yAbsolute = Math.min(Math.max(yAbsolute, 0), screenHeight);

                        Log.e(TAG, "agent 开始处理点击事件，事件转换后坐标，xAbsolute: " + xAbsolute);
                        Log.e(TAG, "agent 开始处理点击事件，事件转换后坐标，yAbsolute: " + yAbsolute);

                        Point point = new Point(xAbsolute, yAbsolute);
                        AccessibilityNodeInfo rootNode = getRootInActiveWindow();
                        if (rootNode != null) {
                            Log.e(TAG, "postRequest: " + "click begin.");
                            performClick(rootNode, point);
                        }
                        Thread.sleep(3000);
                        executeAgentTask(this.currentGlobalTaskPrompt, false);
                    } else if (action.equals("type")) {
                        isActionLineNull = false;
                        Log.e(TAG, "postRequest: " + "开始处理输入事件");

                        AccessibilityNodeInfo focusNode = getRootInActiveWindow().findFocus(AccessibilityNodeInfo.FOCUS_INPUT);
                        if (focusNode != null && "android.widget.EditText".equals(focusNode.getClassName())) {
                            Bundle bundle = new Bundle();
                            bundle.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, typeContent);
                            focusNode.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, bundle);
                            Thread.sleep(2000);
                            executeAgentTask(this.currentGlobalTaskPrompt, false);
                        }

                    }
                }


            } catch (IOException | JSONException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }).start();
        return null;
    }

    private void performClick(AccessibilityNodeInfo rootNode, Point point) {
        GestureDescription.Builder builder = new GestureDescription.Builder();
        Path path = new Path();
        path.moveTo(point.x, point.y);
        GestureDescription.StrokeDescription strokeDescription = new GestureDescription.StrokeDescription(path, 0, 1000);
        builder.addStroke(strokeDescription);
        GestureDescription gesture = builder.build();
        dispatchGesture(gesture, new GestureResultCallback() {
            @Override
            public void onCompleted(GestureDescription gestureDescription) {
                super.onCompleted(gestureDescription);
            }

            @Override
            public void onCancelled(GestureDescription gestureDescription) {
                super.onCancelled(gestureDescription);
            }
        }, null);
    }

    @Override
    protected void onServiceConnected() {
        super.onServiceConnected();
        Log.e(TAG, "onServiceConnected");

        createFloatingWindow();

        task_step = 0;
        AccessibilityServiceInfo info = new AccessibilityServiceInfo();
        info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
        info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
        info.notificationTimeout = 100;
        setServiceInfo(info);

//        Log.e(TAG, "开始执行本轮循环任务");
//        executeAgentTask("使用滴滴打车，出发地：华为研究研究所南门，目的地：夫子庙");

        // 初始化 LLMEngineRequest
        this.context = getApplicationContext(); // 确保 context 已初始化
        this.llmEngineRequest = new LLMEngineRequest(this.context, apiKey);

        // 设定初始的全局任务指令
        // 这个指令可以来自用户界面、固定值或通过其他方式获取
        startNewGlobalTask("使用滴滴打车，出发地：上海东方万国E2，目的地：MORTONS(上海ifc商场点)");
    }

    /**
     * 开始一个新的全局任务。会重置LLM的对话历史。
     *
     * @param globalTaskPrompt 整个任务的用户指令，例如 "帮我用滴滴打车从A到B"
     */
    public void startNewGlobalTask(String globalTaskPrompt) {
        this.currentGlobalTaskPrompt = globalTaskPrompt;
        task_step = 0; // 重置任务步骤计数器
        Log.e(TAG, "开始新的全局任务: " + globalTaskPrompt);
        try {
            // 读取系统提示
            String systemPrompt = llmEngineRequest.readTxtFromAssets(this.context, "systemprompt.txt");
            if (systemPrompt == null) {
                systemPrompt = "You are a helpful AI assistant that controls a smartphone GUI to complete tasks based on user instructions and screen observations."; // Fallback
            }
            // 重置对话历史，并设置新的系统提示和初始用户任务
            // 注意：这里我们将初始用户任务作为第一条用户消息传递，而不是混在系统提示里。
            // 或者，如果你的 systemprompt.txt 已经包含了任务引导，可以只传递 systemPrompt
            llmEngineRequest.resetConversation(systemPrompt);

            // 第一次执行任务，传入的是整个任务的指令
            executeAgentTask(this.currentGlobalTaskPrompt, true); // true 表示这是任务的第一步

        } catch (JSONException e) {
            Log.e(TAG, "Failed to reset LLM conversation for new global task", e);
        }
    }

    private void createFloatingWindow() {
        windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        LayoutInflater inflater = LayoutInflater.from(this);
        floatingView = inflater.inflate(R.layout.floating_window, null); // Use your layout file

        // Initialize the TextView
        llmActionTextView = floatingView.findViewById(R.id.llm_action_textview); // Get the TextView
        final EditText userPromptEditText = floatingView.findViewById(R.id.userPrompt);
        Button runTaskButton = floatingView.findViewById(R.id.gui_agent_action_button);

        runTaskButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String userCommand = userPromptEditText.getText().toString();
                if (!userCommand.isEmpty()) {
                    Log.i(TAG, "Run Task button clicked. Command: " + userCommand);
                    updateLLMActionDisplay("Starting task: " + userCommand); // Update display
                    startNewGlobalTask(userCommand); // Start the task
                } else {
                    Log.w(TAG, "User command input is empty on button click.");
                    updateLLMActionDisplay("Please enter a command before running.");
                }
            }
        });


        int layoutParamsType;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            layoutParamsType = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
        } else {
            layoutParamsType = WindowManager.LayoutParams.TYPE_PHONE;
        }

        params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                layoutParamsType,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                PixelFormat.TRANSLUCENT);

        params.gravity = Gravity.TOP | Gravity.START;
        params.x = 0;
        params.y = 100;

        try {
            if (floatingView.getWindowToken() == null && floatingView.getParent() == null) {
                windowManager.addView(floatingView, params);
                Log.d(TAG, "Floating window added.");
                updateLLMActionDisplay("Ready."); // Initial message
            }
        } catch (Exception e) {
            Log.e(TAG, "Error adding floating window", e);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy(); // Fixed: Added closing parenthesis
//        if (floatingView != null && windowManager != null) {
//            windowManager.removeView(floatingView);
//        }
    }

    private void llmEngineProcess(String fileName, String userPrompt, boolean isFirstStepOfGlobalTask) {
        Log.e(TAG, "gui agent：" + "开始做大模型推理");
        postRequest(fileName, userPrompt, isFirstStepOfGlobalTask);
    }

    private void executeAgentTask(String userPromptForThisStep, boolean isFirstStepOfGlobalTask) {
        //  在 onServiceConnected 中确保 this.context 被初始化
        if (this.context == null) {
            Log.e(TAG, "Context is null in executeAgentTask. Initializing.");
            this.context = getApplicationContext();
            if (this.context == null) {
                Log.e(TAG, "Failed to initialize context in executeAgentTask. Cannot proceed.");
                return; // 无法获取context，则无法继续
            }
        }
        if (llmEngineRequest == null) {
            Log.e(TAG, "llmEngineRequest is not initialized in executeAgentTask!");
            //尝试重新初始化，但这可能表明之前的流程有问题
            this.llmEngineRequest = new LLMEngineRequest(this.context, apiKey);
            try {
                String systemPrompt = llmEngineRequest.readTxtFromAssets(this.context, "systemprompt.txt");
                if (systemPrompt == null) systemPrompt = "Default system prompt";
                llmEngineRequest.resetConversation(systemPrompt); // 如果重新初始化，也需要重置
            } catch (JSONException e) {
                Log.e(TAG, "Failed to reset LLM conversation after re-initialization", e);
                return;
            }
        }


        takeScreenshot(new ScreenshotSaveCallback() {
            @Override
            public void onSuccess(String fileName) {
                // 不再在新的线程中调用 llmEngineProcess，因为 postRequest 内部已经创建了线程
                Log.e(TAG, "用户本步骤的prompt是：" + userPromptForThisStep + (isFirstStepOfGlobalTask ? " (任务第一步)" : ""));
                llmEngineProcess(fileName, userPromptForThisStep, isFirstStepOfGlobalTask);
            }

            @Override
            public void onFailure(String errorMessage) {
                Log.e(TAG, "Screenshot failed: " + errorMessage + ". Cannot execute agent task.");
                // 考虑如何处理截图失败的情况，例如重试或通知用户
            }
        });
    }

    private void takeScreenshot(ScreenshotSaveCallback callback) {
        Log.e(TAG, "takeScreenshot: " + "开始截屏");
        context = getApplicationContext();
        final String[] fileName = {""};
        takeScreenshot(Display.DEFAULT_DISPLAY,
                context.getMainExecutor(),
                new TakeScreenshotCallback() {
                    @Override
                    public void onSuccess(@NonNull ScreenshotResult screenshot) {
                        Bitmap bitmap = Bitmap.wrapHardwareBuffer(screenshot.getHardwareBuffer(), null);
                        String fileName = saveImage(bitmap);
                        if (callback != null) {
                            callback.onSuccess(fileName);
                        }
                    }

                    @Override
                    public void onFailure(int errorCode) {
                        Log.e(TAG, "截图失败，错误码：" + errorCode);
                        if (callback != null) {
                            callback.onFailure(String.valueOf(errorCode));
                        }
                    }
                });
    }

    private String saveImage(Bitmap bitmap) {
        String fileName = task_step + ".png";
        saveBitmapToPrivateDirectory(context, bitmap, fileName);
        task_step++;
        return fileName;
    }

    private boolean saveBitmapToPrivateDirectory(Context context, Bitmap bitmap, String fileName) {
        File externalFilesDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        if (externalFilesDir == null) {
            externalFilesDir = context.getFilesDir();
        }

        File file = new File(externalFilesDir, fileName);
        Log.e(TAG, "saveBitmapToPrivateDirectory: " + file.getPath());
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.flush();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
